home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 4490 / 4490.xpi / components / WebMailNotifier.js < prev    next >
Text File  |  2010-01-29  |  54KB  |  1,561 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is WebMail Notifier.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Byungwook Kang.
  18.  * Portions created by the Initial Developer are Copyright (C) 2007
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  25.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26.  * in which case the provisions of the GPL or the LGPL are applicable instead
  27.  * of those above. If you wish to allow use of your version of this file only
  28.  * under the terms of either the GPL or the LGPL, and not to allow others to
  29.  * use your version of this file under the terms of the MPL, indicate your
  30.  * decision by deleting the provisions above and replace them with the notice
  31.  * and other provisions required by the GPL or the LGPL. If you do not delete
  32.  * the provisions above, a recipient may use your version of this file under
  33.  * the terms of any one of the MPL, the GPL or the LGPL.
  34.  *
  35.  * ***** END LICENSE BLOCK ***** */
  36.  
  37. /***********************************************************
  38. constants
  39. ***********************************************************/
  40.  
  41. const nsIWebMailNotifier = Components.interfaces.nsIWebMailNotifier;
  42.  
  43. // UUID uniquely identifying our component
  44. const CLASS_ID = Components.ID("{e3ab0980-b4e1-11db-abbd-0800200c9a66}");
  45.  
  46. // description
  47. const CLASS_NAME = "WebMail Notifier Service";
  48.  
  49. // textual unique identifier
  50. const CONTRACT_ID = "@mozilla.org/WebMailNotifier;1";
  51.  
  52. const ST_PRE         = 0;
  53. const ST_PRE_RES     = 1;
  54. const ST_LOGIN       = 10;
  55. const ST_LOGIN_RES   = 11;
  56. const ST_DATA        = 20;
  57. const ST_DATA_RES    = 21;
  58.  
  59. const LOGIN_URL      = 0;
  60. const LOGIN_ID       = 1;
  61. const LOGIN_PW       = 2;
  62. const LOGIN_DATA     = 3;
  63. const LOGIN_POST     = 1;
  64.  
  65. const formSubmitURL = "user";
  66.  
  67. const dout=Components.utils.reportError;
  68.  
  69. var enableDebug=false;
  70. /***********************************************************
  71. class definition
  72. ***********************************************************/
  73.  
  74. //class constructor
  75. function WebMailNotifier() {
  76.   var observerService = Components.classes["@mozilla.org/observer-service;1"]
  77.                                 .getService(Components.interfaces.nsIObserverService);
  78.   observerService.addObserver(this, "http-on-modify-request", false);
  79.   observerService.addObserver(this, "http-on-examine-response", false);
  80.   //for uninstall
  81.   this.uninstall=false;
  82.   observerService.addObserver(this, "em-action-requested", false);
  83.   observerService.addObserver(this, "quit-application-granted", false);
  84.  
  85.   //init preferences
  86.   var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  87.                               .getService(Components.interfaces.nsIPrefService);
  88.   this.prefBranch = prefService.getBranch("extensions.wmn.");
  89.   this.prefBranch.QueryInterface(Components.interfaces.nsIPrefBranch2);
  90.   this.prefBranch.addObserver("", this, false);
  91.   this.timerDelay=this.prefBranch.getIntPref("updateInterval")*60000;
  92.   this.connectionDelay=this.prefBranch.getIntPref("connectionDelay")*1000;
  93.   this.newMailsOnly=this.prefBranch.getBoolPref("newMailsOnly");
  94.  
  95.   var tmp=this;
  96.   this.worker={
  97.     notify:function(aTimer){
  98.       WebMailNotifier.prototype.timerWork.call(tmp,aTimer);
  99.     }
  100.   };
  101.   this.timer = Components.classes["@mozilla.org/timer;1"]
  102.                 .createInstance(Components.interfaces.nsITimer);
  103.   this.workTimer = Components.classes["@mozilla.org/timer;1"]
  104.                 .createInstance(Components.interfaces.nsITimer);
  105.  
  106.  
  107.   enableDebug=this.prefBranch.getIntPref("debug");
  108.  
  109.   if ("@mozilla.org/login-manager;1" in Components.classes){
  110.     this.loginManager = Components.classes["@mozilla.org/login-manager;1"]
  111.                            .getService(Components.interfaces.nsILoginManager);
  112.   }else if ("@mozilla.org/passwordmanager;1" in Components.classes){
  113.     this.passwordManager = Components.classes["@mozilla.org/passwordmanager;1"]
  114.                                   .getService(Components.interfaces.nsIPasswordManager);
  115.   }
  116. }
  117. // class definition
  118. WebMailNotifier.prototype = {
  119.   listeners : new Array(),
  120.   timer : null,
  121.   inited : false,
  122.   initCalled : false,
  123.   countTotal : 0,
  124.   QueryInterface: function(aIID)
  125.   {
  126.     if (!aIID.equals(nsIWebMailNotifier) &&
  127.         !aIID.equals(Components.interfaces.nsISupports))
  128.       throw Components.results.NS_ERROR_NO_INTERFACE;
  129.     return this;
  130.   }
  131. }
  132. WebMailNotifier.prototype.init=function() {
  133.   var str="chrome://wmn/options";
  134.   var str2="autoLogin";
  135.   this.autoLogin=this.getPassword(str,str2);
  136.   if(this.autoLogin==null){
  137.     this.autoLogin=this.prefBranch.getBoolPref("autoLoginDefault")?1:0;
  138.     this.setPassword(str,str2,this.autoLogin);
  139.   }else this.autoLogin=parseInt(this.autoLogin);
  140.  
  141.   this.bundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
  142.            .getService(Components.interfaces.nsIStringBundleService)
  143.            .createBundle("chrome://wmn/locale/overlay.properties"),
  144.  
  145.   this.userScripts={};
  146.   this.scripts={};
  147.   this.initScripts(true);
  148.   this.initScripts(false);
  149.  
  150.   this.initHandlers(true);
  151.   if(this.prefBranch.getBoolPref("startupOpenWMN"))this.openWMN();
  152. }
  153.  
  154. WebMailNotifier.prototype.initScripts = function(isDefault) {
  155.   var ios = Components.classes["@mozilla.org/network/io-service;1"]
  156.                       .getService(Components.interfaces.nsIIOService);
  157.   var fileHandler = ios.getProtocolHandler("file")
  158.                        .QueryInterface(Components.interfaces.nsIFileProtocolHandler);
  159.   var loader =  Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
  160.                   .getService(Components.interfaces.mozIJSSubScriptLoader);
  161.   var file;
  162.   if(isDefault){
  163.     file=__LOCATION__.parent;
  164.     var dir=fileHandler.getURLSpecFromFile(file);
  165.     var info = Components.classes["@mozilla.org/xre/app-info;1"]  
  166.              .getService(Components.interfaces.nsIXULAppInfo);  
  167.     if(info.name=="Thunderbird"){
  168.       loader.loadSubScript(dir+"ui-tb.js");
  169.     }else{
  170.       loader.loadSubScript(dir+"ui.js");  
  171.     }      
  172.     
  173.     file.append("scripts");
  174.     this.dir0=fileHandler.getURLSpecFromFile(file);
  175.     try{
  176.       loader.loadSubScript(this.dir0+"order.dat",this);
  177.     }catch(e){dout(e);}
  178.   }else{
  179.     file = Components.classes["@mozilla.org/file/directory_service;1"]
  180.                      .getService(Components.interfaces.nsIProperties)
  181.                      .get("ProfD", Components.interfaces.nsIFile);
  182.     file.append("wmn");
  183.     this.dir1=fileHandler.getURLSpecFromFile(file);
  184.     if(this.dir1.charAt(this.dir1.length-1)!="/"){//folder not exist
  185.       this.dir1+="/";
  186.     }
  187.   }
  188.   if(file.exists()){
  189.     var entries = file.directoryEntries;
  190.     while(entries.hasMoreElements())
  191.     {
  192.       var t = entries.getNext();
  193.       t.QueryInterface(Components.interfaces.nsIFile);
  194.       var s=t.leafName;
  195.       var fnd;
  196.       if(fnd=s.match(/((lib-)?.+).js$/)){
  197.         if(fnd[2]){//load library
  198.           try{
  199.             loader.loadSubScript((isDefault?this.dir0:this.dir1)+fnd[0]);
  200.           }catch(e){
  201. dout(fnd[0]+" "+e);
  202.           }
  203.         }else{
  204.           this.scripts[fnd[1]]=null;
  205.         }
  206.         if(!isDefault)this.userScripts[fnd[1]]=true;
  207.       }
  208.     }
  209.   }
  210. }
  211. WebMailNotifier.prototype.initHandler = function(obj,id,user,pass) {
  212.   this.webMailHandlers.push(obj);        
  213.   obj.id=id;        
  214.   obj.user=user;     
  215.   obj.password=pass;
  216.   obj.inited=false;
  217.   if(this.order[id])obj.key=this.order[id].toString();
  218. }
  219. WebMailNotifier.prototype.initHandlers = function(aCheckNow) {
  220. //dout("***initHandlers "+aCheckNow);
  221.   this.stopAll();
  222.   this.webMailHandlers=[];
  223.   var str="chrome://wmn/accounts/";
  224.   if(this.loginManager){
  225.     for(var id in this.scripts){
  226.       var logins = this.loginManager.findLogins({},str+id,formSubmitURL, null);
  227.       for each (var o in logins) {
  228.         var obj=new WebMailHandler(this);
  229.         this.initHandler(obj,id,o.username,o.password);
  230.       }
  231.     }
  232.   }else{
  233.     var e = this.passwordManager.enumerator;
  234.     while (e.hasMoreElements()) {
  235.       try {
  236.         var pass = e.getNext().QueryInterface(Components.interfaces.nsIPassword);
  237.         if (pass.host.indexOf(str)==0) {
  238.           var id=pass.host.substring(str.length);
  239.           var obj=new WebMailHandler(this);
  240.           this.initHandler(obj,id,pass.user,pass.password);
  241.         }
  242.       }catch(ex) {}
  243.     }
  244.   }
  245.   this.webMailHandlers.sort(this.sortFunc);
  246.   this.buildTable(aCheckNow);
  247. }
  248. WebMailNotifier.prototype.sortFunc = function(a,b) {
  249.   var keyA=a.key?a.key:a.id;
  250.   var keyB=b.key?b.key:b.id;
  251.   if(keyA<keyB)return -1;
  252.   else if(keyA==keyB){
  253.     if(a.user<b.user)return -1;
  254.     else if(a.user==b.user)return 0;
  255.     else return 1;
  256.   }else return 1;
  257. }
  258. WebMailNotifier.prototype.loadScript = function(id,isTemp) {
  259.   var loader =  Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
  260.                   .getService(Components.interfaces.mozIJSSubScriptLoader);
  261.   if(!this.scripts[id]){
  262. //dout("loadScript "+(this.userScripts[id]?this.dir1:this.dir0)+id+".js");
  263.     var scr={};
  264.     loader.loadSubScript((this.userScripts[id]?this.dir1:this.dir0)+id+".js",scr);
  265. //dout("loaded "+id+" "+isTemp);
  266.     if(!isTemp)this.scripts[id]=scr;
  267. //if(!isTemp)dout("load ["+id+"] "+scr.name);
  268.     return scr;
  269.   }else return this.scripts[id];
  270. }
  271. WebMailNotifier.prototype.buildTable = function(aCheckNow) {
  272.   this.stopAll();
  273. //dout("***buildTable "+aCheckNow);
  274.   var loader =  Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
  275.                   .getService(Components.interfaces.mozIJSSubScriptLoader);
  276.   var i;
  277.   for(i=0;i<this.webMailHandlers.length;++i){
  278.     var obj=this.webMailHandlers[i];
  279.     try{
  280.       obj.enabled=this.prefBranch.getBoolPref("accounts."+obj.id+"."+obj.user+".enabled");
  281.     }catch(e){}
  282.     if(!obj.enabled||obj.inited)continue;
  283. //dout("init "+obj.id+" "+obj.user);
  284.     try{
  285.       this.loadScript(obj.id);
  286.       var scr=this.scripts[obj.id];
  287.       for(var k in scr){
  288.         obj[k]=scr[k];
  289.       }
  290.       if(obj.supportInboxOnly)obj.inboxOnly=obj.isInboxOnly();
  291.       if(obj.supportShowFolders)obj.showFolders=obj.isShowFolders();;      
  292.       if(obj.needServer)obj.server=obj.user.split("|")[1];      
  293.       if(obj.init)obj.init();
  294.       if(obj.loginData){
  295.         var post=(obj.loginData[LOGIN_DATA]?obj.loginData[LOGIN_DATA]:"");
  296.         if(obj.loginData[LOGIN_ID]){
  297.           if(post)post+="&";
  298.           var user;
  299.           if(obj.needServer)user=obj.user.split("|")[0];
  300.           else user=obj.user;
  301.           post+=obj.loginData[LOGIN_ID]+"="+encodeURIComponent(user);
  302.         }
  303.         if(obj.loginData[LOGIN_PW]){
  304.           if(post)post+="&";
  305.           post+=obj.loginData[LOGIN_PW]+"="+encodeURIComponent(obj.password);
  306.         }
  307.         obj.loginData.splice(1,obj.loginData.length-1);
  308.         obj.loginData[LOGIN_POST]=post;
  309.       }
  310.       obj.stage=obj.initStage;
  311.       obj.inited=true;
  312.     }catch(e){
  313. dout(obj.id+" "+e);
  314.       this.webMailHandlers.splice(i,1);//not loaded
  315.       --i;
  316.     }
  317.   }
  318.   for(i=0;i<this.webMailHandlers.length;++i){
  319.     this.webMailHandlers[i].ind=i;
  320.   }
  321.  
  322.   this.hdlTable={};
  323.   var defaults={};
  324.   for(var i in this.scripts){
  325.     this.hdlTable[i]=[];
  326.     try{
  327.       defaults[i]=this.prefBranch.getCharPref("accounts."+i+".default");
  328.     }catch(e){}
  329.   }
  330.   var maxLen=0;
  331.   for each(var o in this.webMailHandlers){
  332.     if(o.enabled){
  333.       if(o.user==defaults[o.id])this.hdlTable[o.id].splice(0,0,o);//default account inserted into index 0
  334.       else this.hdlTable[o.id].push(o);
  335.       if(this.hdlTable[o.id].length>maxLen)maxLen=this.hdlTable[o.id].length;
  336.       o.name=this.getHostName(o.id);
  337.     }
  338.   }
  339.   for(var i in this.hdlTable){
  340.     var o=this.hdlTable[i];
  341.     if(o.length>0){
  342.       var prefStr="accounts."+i+".default";
  343.       var t=null;
  344.       try{
  345.         t=this.prefBranch.getCharPref(prefStr);
  346.       }catch(e){}
  347.       if(t==null)this.prefBranch.setCharPref(prefStr,o[0].user);
  348.       //set account name
  349.       for each(var obj in o){
  350.         if(o.length>1){
  351.           obj.accName=obj.name+" ["+obj.user+"]";
  352.         }else obj.accName=obj.name;
  353.       }
  354.     }
  355.   }
  356.  
  357.   this.workTable=[];
  358.   var cons=Math.max(1,this.prefBranch.getIntPref("connections"));
  359.   for(var n=0;n<maxLen;n+=cons){
  360.     var ar=[];
  361.     this.workTable.push(ar);
  362.     for(var i in this.hdlTable){
  363.       var o=this.hdlTable[i];
  364.       for(var j=n;j<n+cons&&j<o.length;j++){
  365.         ar.push(o[j]);
  366.       }
  367.     }
  368.   }
  369.   if(aCheckNow){
  370.     this.setState(nsIWebMailNotifier.ST_RESET,0);
  371.     this.checkMails();
  372.   }
  373. }
  374. WebMailNotifier.prototype.isDefault = function(id,user) {
  375.   return this.hdlTable[id].length==1||(this.hdlTable[id].length>1&&this.hdlTable[id][0].user==user);
  376. }
  377.  
  378. WebMailNotifier.prototype.isOpenable = function(id,user) {
  379.   if(this.hdlTable[id].length==1)return true;
  380.   else if(this.hdlTable[id].length==0)return false;
  381.   var ar=this.hdlTable[id];
  382.   for(var i=0;i<ar.length;i++){
  383.     if(ar[i].user==user)break;
  384.     if(ar[i].calcCount()>0)return false;
  385.   }
  386.   return true;
  387. }
  388. WebMailNotifier.prototype.addScript = function(id) {
  389.   var rs=this.scripts[id];
  390.   if(id.indexOf("lib-")==0){
  391.     try{
  392.       var loader =  Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
  393.                   .getService(Components.interfaces.mozIJSSubScriptLoader);
  394.       loader.loadSubScript(this.dir1+id+".js");
  395.     }catch(e){
  396. dout("load library "+e);
  397.     }
  398.   }else{
  399.     this.scripts[id]=null;
  400.   }
  401.   this.userScripts[id]=true;
  402.   return rs?true:false; //'return rs' returns wrong value
  403. }
  404.  
  405. WebMailNotifier.prototype.getHostIDs = function(count) {
  406.   var ar=[];
  407.   for(var i in this.scripts){
  408.     var o={id:i};
  409.     if(this.order[i])o.key=this.order[i].toString();
  410.     ar.push(o);
  411.   }
  412.   ar.sort(this.sortFunc);
  413.   var ar2=[];
  414.   for each(var o in ar)ar2.push(o.id);
  415.   count.value=ar2.length;
  416.   return ar2;
  417. }
  418. WebMailNotifier.prototype.getScriptList = function(count) {
  419.   var ar=[];
  420.   for(var i in this.userScripts){
  421.     ar.push(i);
  422.   }
  423.   count.value=ar.length;
  424.   return ar;
  425. }
  426. WebMailNotifier.prototype.isInstalled = function(id) {
  427.   for(var i in this.userScripts){
  428.     if(i==id)return true;
  429.   }
  430.   return false;
  431. }
  432. WebMailNotifier.prototype.getAccountsInHost = function(id) {
  433.   return this.hdlTable[id].length;
  434. }
  435. WebMailNotifier.prototype.getHostName = function(id) {
  436.   try{
  437.     return this.bundle.GetStringFromName(id);
  438.   }catch(e){}
  439.   try{
  440.     var obj=this.loadScript(id,true);
  441.     return obj.name?obj.name:id;
  442.   }catch(e){
  443. dout("getHostName:"+id+" "+e);
  444.     return id;
  445.   };
  446. }
  447. WebMailNotifier.prototype.getScriptVal = function(id,name) {
  448.   try{
  449.     var obj=this.loadScript(id,true);
  450.     return obj[name];
  451.   }catch(e){
  452.     return null;
  453.   };
  454. }
  455. WebMailNotifier.prototype.getAccountsNumber = function() {
  456.   return this.webMailHandlers.length;
  457. }
  458. WebMailNotifier.prototype.getAccountInfo = function(count,aIndex) {
  459.   var obj=this.webMailHandlers[aIndex];
  460.   var ar=[obj.id,obj.user,obj.password];
  461.   count.value=ar.length;
  462.   return ar;
  463. }
  464. WebMailNotifier.prototype.isAccountEnabled = function(aIndex) {
  465.   return this.webMailHandlers[aIndex].enabled;
  466. }
  467. WebMailNotifier.prototype.getIntValue = function(name) {
  468.   return this[name];
  469. }
  470. WebMailNotifier.prototype.setIntValue = function(name,val) {
  471.   this[name]=val;
  472. }
  473.  
  474. WebMailNotifier.prototype.addListener = function(aListener) {
  475.   this.listeners.push(aListener);
  476.   if(!this.inited){
  477.     if(!this.initCalled){
  478.       this.initCalled=true;
  479.       this.init();
  480.       for each(var l in this.listeners){
  481.         l.onStateChange(nsIWebMailNotifier.ST_INIT,0,null);
  482.         for each(var o in this.webMailHandlers){
  483.           if(o.enabled){
  484.             l.onStateChange(o.ind,o.calcCount(),encodeObject(o.mailData));
  485.           }
  486.         }
  487.       }
  488.       this.inited=true;
  489.     }
  490.   }else{
  491.     aListener.onStateChange(nsIWebMailNotifier.ST_INIT,0,null);
  492.     for each(var o in this.webMailHandlers){
  493.       if(o.enabled){
  494.         aListener.onStateChange(o.ind,o.calcCount(),encodeObject(o.mailData));
  495.       }
  496.     }
  497.   }
  498. }
  499. WebMailNotifier.prototype.removeListener = function(aListener){
  500.   for(var i=0;i<this.listeners.length;i++){
  501.     if(this.listeners[i]==aListener){
  502.         this.listeners.splice(i,1);
  503.         break;
  504.     }
  505.   }
  506. }
  507. WebMailNotifier.prototype.checkMail = function(aIndex) {
  508.   var o=this.webMailHandlers[aIndex];
  509.   o.runCount=0;//used in webupdate notifier
  510.   o.checkMail();
  511. }
  512. WebMailNotifier.prototype.stopAll = function() {
  513.   this.timer.cancel();
  514.   this.workTimer.cancel();
  515.   for each(var o in this.webMailHandlers){
  516.     if(o.started)o.stop();
  517.   }
  518. }
  519. WebMailNotifier.prototype.checkMails = function(isTimer) {
  520.   if(this.workTable.length>1){
  521.     this.workTimer.cancel();
  522.     this.workTimer.initWithCallback(this.worker,
  523.                                 this.connectionDelay,
  524.                                 Components.interfaces.nsITimer.TYPE_ONE_SHOT);
  525.   }
  526.   for each(var o in this.webMailHandlers){
  527.     if(o.enabled){
  528.       o.started=true;
  529.       if(!isTimer)o.runCount=0;
  530.     }
  531.   }
  532.   this.workDone=1;
  533.   for each(var o in this.workTable[0]){
  534.     o.checkMail();
  535.   }
  536.   this.setTimer();
  537. }
  538. WebMailNotifier.prototype.timerWork = function(aTimer) {
  539.   for each(var o in this.workTable[this.workDone]){
  540.     o.checkMail();
  541.   }
  542.   ++this.workDone;
  543.   if(this.workDone<this.workTable.length){
  544.     this.workTimer.initWithCallback(this.worker,
  545.                                 this.connectionDelay,
  546.                                 Components.interfaces.nsITimer.TYPE_ONE_SHOT);
  547.   }
  548. }
  549. WebMailNotifier.prototype.getHandler = function(aID,aUser) {
  550.   for each(var i in this.webMailHandlers){
  551.     if(i.id==aID&&i.user==aUser)return i;
  552.   }
  553.   return null;
  554. }
  555. WebMailNotifier.prototype.getMailURL = function(aID,aUser,aFolder) {
  556.   var obj=this.getHandler(aID,aUser);
  557.   if(obj){
  558.     if(this.autoLogin&&!obj.noCookie)obj.cookieManager.setCookieToBrowser();
  559.     if(this.newMailsOnly){
  560.       var url=obj.getMailURL(aFolder);
  561.       var pref="accounts."+aID+"."+aUser+".count";
  562.       try{
  563.         this.prefBranch.getIntPref(pref);//set only if this exists
  564.         this.prefBranch.setIntPref(pref,obj.mailCount>0?obj.mailCount:0);
  565.       }catch(e){}
  566.       obj.mailData.desc=obj.getDesc();
  567.       this.setState(nsIWebMailNotifier.ST_MAILDATA,obj.ind);
  568.       return url;
  569.     }else return obj.getMailURL(aFolder);
  570.   }else return null;
  571. }
  572. WebMailNotifier.prototype.getIconURL = function(aID,aUser) {
  573.   var obj=this.getHandler(aID,aUser);
  574.   if(obj)return obj.getIconURL();
  575.   else return null;
  576. }
  577. WebMailNotifier.prototype.getMailDomain = function(aID,aUser) {
  578.   var obj=this.getHandler(aID,aUser);
  579.   if(obj&&obj.mailDomain)return obj.mailDomain;
  580.   else return null;
  581. }
  582.  
  583. WebMailNotifier.prototype.setState = function(aCmd,aIndex) {
  584.   var aData=null;
  585.   var aCount=0;
  586.   if(aCmd==nsIWebMailNotifier.ST_MAILDATA){
  587.     var o=this.webMailHandlers[aIndex];
  588.     o.started=false;
  589.     aData=encodeObject(o.mailData);
  590.     aCount=o.calcCount();
  591.     var finished=true;
  592.     for each(o in this.webMailHandlers){
  593.       if(o.started){
  594.         finished=false;
  595.         break;
  596.       }
  597.     }
  598.     if(finished){
  599.       var total=0;
  600.       for each(o in this.webMailHandlers){
  601.         if(o.enabled&&o.mailCount>0){
  602.           total+=o.calcCount();
  603.         }
  604.       }
  605.       if(total>this.countTotal)this.notification(total);
  606.       else if(this.countTotal>0&&total==0){
  607.           var win=this.findWindow("alert:alert","wmn_alert");
  608.           if(win)win.close();
  609.       }
  610.       this.countTotal=total;
  611. //dout("all done");
  612.     }
  613.   }else{//special command
  614.     aCount=aIndex;
  615.     aIndex=aCmd;
  616.   }
  617.   for(var i=0;i<this.listeners.length;i++){
  618.     if(this.listeners[i]){
  619.       this.listeners[i].onStateChange(aIndex,aCount,aData);
  620.     }
  621.   }
  622. }
  623. WebMailNotifier.prototype.notification = function(total) {
  624.   if(this.prefBranch.getBoolPref("mailAlert")){
  625.     if(this.listeners.length>0){
  626.       this.showAlertNotification(total);
  627.     }
  628.   }
  629.   if(this.prefBranch.getBoolPref("mailSound")){
  630.     if (!this.mSound)this.mSound = Components.classes["@mozilla.org/sound;1"].createInstance(Components.interfaces.nsISound);
  631.  
  632.     var soundLocation = this.prefBranch.getBoolPref("customSound")?
  633.               this.prefBranch.getCharPref("soundUrl") : "_moz_mailbeep";
  634.     if (soundLocation.indexOf("file://") == -1){
  635.       var os = Components.classes["@mozilla.org/xre/app-info;1"]
  636.                   .getService(Components.interfaces.nsIXULRuntime).OS;
  637.       if(os=="Darwin")soundLocation="";
  638.       this.mSound.playSystemSound(soundLocation);
  639.     }else{
  640.       var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  641.       try{
  642.         this.mSound.play(ioService.newURI(soundLocation, null, null));
  643.       }catch(e){}
  644.     }
  645.   }
  646. }
  647. WebMailNotifier.prototype.openMails = function(openAll){
  648.   var list=[];
  649.   for each(var o in this.webMailHandlers){
  650.     if(o.enabled){
  651.       if((o.mailCount>0&&o.calcCount()>0&&this.isOpenable(o.id,o.user))
  652.         ||(openAll&&this.isDefault(o.id,o.user))){
  653.         list.push(o);
  654.       }
  655.     }
  656.   }
  657.   for each(var o in list)this.openMail(o.ind);
  658. }
  659. WebMailNotifier.prototype.openMail = function(ind,folder){
  660.   var obj=this.webMailHandlers[ind];
  661.   var id=obj.id;
  662.   var user=obj.user;
  663.   var url=this.getMailURL(id,user,folder);//call this for mailCount set
  664.   if(!url)return;
  665.   var mailDomain=this.getMailDomain(id,user);
  666.   var reuse=this.prefBranch.getBoolPref("reuseWindow");
  667.   if(this.prefBranch.getBoolPref("openInTab")){
  668.     this.openTab(url,"wmn_"+id,reuse,mailDomain);
  669.   }else this.openWindow(url,"wmn_"+id,reuse,mailDomain);
  670. }
  671. WebMailNotifier.prototype.canReuse = function(cur,mailDomain) {
  672.     if(cur.spec=="about:blank"||!mailDomain)return true;
  673.     var host=null;
  674.     try{
  675.       host=cur.host;
  676.     }catch(e){}
  677.     if(!host)return false;
  678.     try{
  679.       var reg=new RegExp(mailDomain);
  680.       if(!host.match(reg))return false;
  681.     }catch(e){}
  682.     return true;
  683. }
  684.  
  685. WebMailNotifier.prototype.findWindow = function(type,name){
  686.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  687.            .getService(Components.interfaces.nsIWindowMediator);
  688.   var enm = wm.getEnumerator(type);
  689.   while(enm.hasMoreElements()){
  690.     var win = enm.getNext();
  691.     if(win.name==name)return win;
  692.   }
  693.   return null;
  694. }
  695. WebMailNotifier.prototype.openDialog = function(url, name, features) {
  696.   return this.getWindow().openDialog(url,name,features,arguments[3],arguments[4],arguments[5]);
  697. }
  698. WebMailNotifier.prototype.openCaptchaDialog = function(host,user,arg) {
  699.   var params = {inn:{host:this.getHostName(host),user:user,secimage:arg}, out:null};
  700.   var features = "chrome,titlebar,toolbar,centerscreen,modal";
  701.   this.openDialog("chrome://wmn/content/captcha.xul","wmn_"+host+":"+user,features,params).focus();
  702.   if (params.out)return params.out.secword;
  703.   else return null;
  704. }
  705. WebMailNotifier.prototype.showAlertNotification = function(total){
  706.   this.openDialog("chrome://wmn/content/alert.xul","wmn_alert",
  707.       "chrome,dialog=yes,titlebar=no,popup=yes",
  708.       this.webMailHandlers,this).focus();
  709. }
  710. WebMailNotifier.prototype.openWMN = function(){
  711.   this.openDialog("chrome://wmn/content/wmn-window.xul","wmn_win",
  712.       "chrome,toolbar=yes,dialog=no,resizable").focus();  
  713. }
  714. WebMailNotifier.prototype.openOptions = function() {
  715.   var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  716.                               .getService(Components.interfaces.nsIPrefService);
  717.   var branch = prefService.getBranch("browser.preferences.");
  718.   branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
  719.   var instantApply= branch.getBoolPref("instantApply");
  720.   var features = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal");
  721.   this.openDialog("chrome://wmn/content/options.xul","wmn-pref",features).focus();
  722. }
  723. WebMailNotifier.prototype.openInTab = function(url){
  724.   this.openTab(url,null,false,null);
  725. }  
  726. /***********************************************************
  727. timer
  728. ***********************************************************/
  729. WebMailNotifier.prototype.setTimer = function() {
  730.   this.timer.cancel();
  731.   if(this.timerDelay>0){
  732.     try{
  733.       this.timer.initWithCallback(this,
  734.                                   this.timerDelay,
  735.                                   Components.interfaces.nsITimer.TYPE_ONE_SHOT);
  736.     }catch(e){}
  737.   }
  738. }
  739.  
  740. WebMailNotifier.prototype.notify = function(aTimer) {
  741.   this.checkMails(true);
  742. }
  743. /***********************************************************
  744. preference observer
  745. ***********************************************************/
  746. WebMailNotifier.prototype.observe=function(aSubject, aTopic, aData)
  747. {
  748.   switch(aTopic){
  749.   case "nsPref:changed":
  750.     switch (aData) {
  751.     case "updateInterval":
  752.       this.timerDelay=this.prefBranch.getIntPref(aData)*60000;
  753.       this.setTimer();
  754.       break;
  755.     case "newMailsOnly":
  756.       this.newMailsOnly=this.prefBranch.getBoolPref("newMailsOnly");
  757.       for each(var o in this.webMailHandlers){
  758.         if(o.enabled){
  759.           /*if(this.newMailsOnly){
  760.             this.prefBranch.setIntPref("accounts."+o.id+"."+o.user+".count",0);
  761.           }else{*/
  762.           if(!this.newMailsOnly){
  763.             try{        
  764.               this.prefBranch.clearUserPref("accounts."+o.id+"."+o.user+".count");
  765.               o.mailData.desc=o.getDesc();
  766.             }catch(e){
  767. dout(e);            
  768.             }
  769.           }
  770.           this.setState(nsIWebMailNotifier.ST_MAILDATA,o.ind);
  771.         }
  772.       }
  773.       break;
  774.     case "showStatusbarIcon":
  775.       this.setState(nsIWebMailNotifier.ST_SHOWICON,this.prefBranch.getBoolPref("showStatusbarIcon"));
  776.       break;
  777.     }
  778.     break;
  779.   case "http-on-modify-request":
  780.     for each(var i in this.webMailHandlers){
  781.       if(i.channel==aSubject){
  782.         i.onRequest(aSubject.QueryInterface(Components.interfaces.nsIHttpChannel));
  783.         break;
  784.       }
  785.     }
  786.     break;
  787.   case "http-on-examine-response":
  788.     for each(var i in this.webMailHandlers){
  789.       if(i.channel==aSubject){
  790.         i.onResponse(aSubject.QueryInterface(Components.interfaces.nsIHttpChannel));
  791.         break;
  792.       }
  793.     }
  794.     break;
  795.   case "em-action-requested":
  796.     aSubject.QueryInterface(Components.interfaces.nsIUpdateItem);
  797.     if(aSubject.id == "{37fa1426-b82d-11db-8314-0800200c9a66}") {
  798.       if (aData == "item-uninstalled") {
  799.         this.uninstall = true;
  800.       } else if (aData == "item-cancel-action") {
  801.         this.uninstall = false;
  802.       } else if(aData == "item-installed" || aData == "item-upgraded"){// "item-installed" doesn't work
  803.         this.postInstall();
  804.       }
  805.     }
  806.     break;
  807.   case "quit-application-granted":
  808.     if(this.uninstall){
  809.       var str="chrome://wmn/";
  810.       if(this.loginManager){
  811.         var logins = this.loginManager.getAllLogins({});
  812.         for each (var o in logins) {
  813.           if(o.hostname.indexOf(str)==0)this.loginManager.removeLogin(o);
  814.         }
  815.       }else{
  816.         var e = this.passwordManager.enumerator;
  817.         while (e.hasMoreElements()) {
  818.           var o = e.getNext().QueryInterface(Components.interfaces.nsIPassword);
  819.           if (o.host.indexOf(str)==0)this.passwordManager.removeUser(o.host,o.user);
  820.         }
  821.       }
  822.  
  823.       var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  824.                                 .getService(Components.interfaces.nsIPrefService);
  825.       var prefBranch = prefService.getBranch("");
  826.       try{ prefBranch.deleteBranch("extensions.wmn."); }catch(e){}
  827.       prefService.savePrefFile(null);
  828.  
  829.       var ios = Components.classes["@mozilla.org/network/io-service;1"]
  830.                   .getService(Components.interfaces.nsIIOService);
  831.       var fileHandler = ios.getProtocolHandler("file")
  832.                           .QueryInterface(Components.interfaces.nsIFileProtocolHandler);
  833.       var file=fileHandler.getFileFromURLSpec(this.dir1);
  834.       try{file.remove(true);}catch(e){}
  835.     }
  836.     break;
  837.   }
  838. }
  839. WebMailNotifier.prototype.postInstall=function(){
  840.   var s1="accounts.wmn_forum.default.enabled";
  841.   var s2="chrome://wmn/accounts/wmn_forum";
  842.   var val=null;
  843.   try{ val=this.prefBranch.getBoolPref(s1); }catch(e){};
  844.   var restart=false;
  845.   if(this.getPassword(s2,"default")==null){
  846.     this.setPassword(s2,"default","1");
  847.     this.prefBranch.setBoolPref(s1,false);
  848.     restart=true;
  849.   }
  850.   //import previous version
  851.   var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  852.                                 .getService(Components.interfaces.nsIPrefService);
  853.   var pb = prefService.getBranch("");
  854.   var str="chrome://wm-notifier/webmail";
  855.   var str2="chrome://wmn/accounts/";
  856.   var hosts=["daum","naver",null,"nate","gmail","yahoo","hotmail"];
  857.   if(this.loginManager){
  858.     for(var i=0;i<hosts.length;i++){
  859.       var logins = this.loginManager.findLogins({},str+i,formSubmitURL, null);
  860.       for each (var o in logins) {
  861.         var host=hosts[i];
  862.         if(host){
  863.           restart=true;
  864.           this.setPassword(str2+host,o.username,o.password);
  865.           this.removePassword(str+i,o.username);
  866.           try{
  867.             var enabled=pb.getBoolPref("wm-notifier.webmail"+i+"."+o.username+".enabled");
  868.             pb.setBoolPref("extensions.wmn.accounts."+host+"."+o.username+".enabled",enabled);
  869.           }catch(e){}
  870.         }
  871.       }
  872.     }
  873.   }else{
  874.     var e = this.passwordManager.enumerator;
  875.     while (e.hasMoreElements()) {
  876.       try {
  877.         var pass = e.getNext().QueryInterface(Components.interfaces.nsIPassword);
  878.         if (pass.host.indexOf(str)==0) {
  879.           var i=pass.host.substring(str.length);
  880.           var host=hosts[i];
  881.           if(host){
  882.             restart=true;
  883.             this.setPassword(str2+host,pass.user,pass.password);
  884.             this.removePassword(str+i,pass.user);
  885.             try{
  886.               var enabled=pb.getBoolPref("wm-notifier.webmail"+i+"."+pass.user+".enabled");
  887.               pb.setBoolPref("extensions.wmn.accounts."+host+"."+pass.user+".enabled",enabled);
  888.             }catch(e){}
  889.           }
  890.         }
  891.       }catch(ex) {}
  892.     }
  893.   }
  894.   //delete userscript
  895.   this.deleteFile("wmn/aol.js");
  896.   this.deleteFile("wmn/paran.js");
  897.   if(restart)this.initHandlers(true);
  898. }
  899.  
  900. /***********************************************************
  901. password manager
  902. ***********************************************************/
  903. WebMailNotifier.prototype.getPassword=function(host,user){
  904.   if(this.loginManager){
  905.     var logins = this.loginManager.findLogins({},host,formSubmitURL, null);
  906.     for each (var o in logins) {
  907.       if (o.username==user) {
  908.         return o.password;
  909.       }
  910.     }
  911.   }else{
  912.     var e = this.passwordManager.enumerator;
  913.     while (e.hasMoreElements()) {
  914.       try {
  915.         var pass = e.getNext().QueryInterface(Components.interfaces.nsIPassword);
  916.         if (pass.host == host&&pass.user == user) {
  917.            return pass.password;
  918.         }
  919.       }catch(ex) {}
  920.     }
  921.   }
  922.   return null;
  923. }
  924. WebMailNotifier.prototype.setPassword=function(host,user,passwd){
  925.   if(this.loginManager){
  926.     var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
  927.                                                  Components.interfaces.nsILoginInfo,
  928.                                                  "init");
  929.     var loginInfo = new nsLoginInfo(host, formSubmitURL, null, user, passwd, "", "");
  930.  
  931.     var logins = this.loginManager.findLogins({},host,formSubmitURL, null);
  932.     for each (var o in logins) {
  933.       if (o.username==user) {
  934.         this.loginManager.modifyLogin(o,loginInfo);
  935.         return;
  936.       }
  937.     }
  938.     this.loginManager.addLogin(loginInfo);
  939.   }else{
  940.     try{
  941.       this.passwordManager.removeUser(host,user);
  942.     }catch(e){}
  943.     this.passwordManager.addUser(host,user,passwd);
  944.   }
  945. }
  946. WebMailNotifier.prototype.removePassword=function(host,user){
  947.   if(this.loginManager){
  948.     var logins = this.loginManager.findLogins({},host,formSubmitURL, null);
  949.     for each (var o in logins) {
  950.       if (o.username==user) {
  951.         this.loginManager.removeLogin(o);
  952.         break;
  953.       }
  954.     }
  955.   }else{
  956.     try{
  957.       this.passwordManager.removeUser(host,user);
  958.     }catch(e){}
  959.   }
  960. }
  961. WebMailNotifier.prototype.loadFile=function(name){
  962.   var file = Components.classes["@mozilla.org/file/directory_service;1"]
  963.                          .getService(Components.interfaces.nsIProperties)
  964.                          .get("ProfD", Components.interfaces.nsIFile);
  965.   name=name.split("/");
  966.   for each(var o in name)file.append(o);
  967.   return this.loadFile0(file);
  968. }
  969.  
  970. WebMailNotifier.prototype.loadFile0=function(file){
  971.   var str="";
  972.   try {
  973.     var fis = Components.classes["@mozilla.org/network/file-input-stream;1"]
  974.                           .createInstance(Components.interfaces.nsIFileInputStream);
  975.     fis.init(file, 0x01, 0664, 0);
  976.     var is = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
  977.                        .createInstance(Components.interfaces.nsIConverterInputStream);
  978.     is.init(fis, "UTF-8", 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  979.  
  980.     var s = {};
  981.     while (is.readString(4096, s) != 0) {
  982.       str+=s.value;
  983.     }
  984.     is.close();
  985.     fis.close();
  986.   }catch(e){
  987. dout(e);
  988.   }
  989.   return str;
  990. }
  991. WebMailNotifier.prototype.saveFile=function(name,str,append){
  992.   var file = Components.classes["@mozilla.org/file/directory_service;1"]
  993.                      .getService(Components.interfaces.nsIProperties)
  994.                      .get("ProfD", Components.interfaces.nsIFile);
  995.   name=name.split("/");
  996.   for(var i in name){
  997.     file.append(name[i]);
  998.     if(i<name.length-1){
  999.       if(!file.exists()){
  1000.         file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE,0755);
  1001.       }
  1002.     }
  1003.   }
  1004.   return this.saveFile0(file,str,append);
  1005. }
  1006. WebMailNotifier.prototype.saveFile0=function(file,str,append){
  1007.   try{
  1008.     var fos = Components.classes["@mozilla.org/network/file-output-stream;1"]
  1009.                           .createInstance(Components.interfaces.nsIFileOutputStream);
  1010.     fos.init(file, 0x02 | 0x08 |(append?0x10:0x20), 0664, 0);
  1011.     var os = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
  1012.                        .createInstance(Components.interfaces.nsIConverterOutputStream);
  1013.     os.init(fos, "UTF-8", 0, 0x0000);
  1014.     os.writeString(str);
  1015.     os.close();
  1016.     fos.close();
  1017.   }catch(e){
  1018. dout(e);
  1019.   }
  1020.   return file;
  1021. }
  1022. WebMailNotifier.prototype.deleteFile=function(name){
  1023.   var file = Components.classes["@mozilla.org/file/directory_service;1"]
  1024.                      .getService(Components.interfaces.nsIProperties)
  1025.                      .get("ProfD", Components.interfaces.nsIFile);
  1026.   name=name.split("/");
  1027.   for each(var o in name)file.append(o);
  1028.   if(file.exists()){
  1029.     file.remove(false);
  1030.   }
  1031. }
  1032. WebMailNotifier.prototype.removeHost=function(aHostID){
  1033.   try{
  1034.     this.prefBranch.deleteBranch("accounts."+aHostID);
  1035.     var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  1036.                               .getService(Components.interfaces.nsIPrefService);
  1037.     prefService.savePrefFile(null);
  1038.   }catch(e){
  1039. dout(e);
  1040.   }
  1041.   for each(var o in this.webMailHandlers){
  1042.     if(o.id==aHostID){
  1043.       this.removePassword("chrome://wmn/accounts/"+o.id,o.user);
  1044.     }
  1045.   }
  1046.   delete this.scripts[aHostID];
  1047.   delete this.userScripts[aHostID];
  1048. }
  1049. /***********************************************************
  1050. class factory
  1051.  
  1052. This object is a member of the global-scope Components.classes.
  1053. It is keyed off of the contract ID.
  1054. ***********************************************************/
  1055. var WebMailNotifierFactory = {
  1056.   createInstance: function (aOuter, aIID)
  1057.   {
  1058.     if (aOuter != null)
  1059.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  1060.     return (new WebMailNotifier()).QueryInterface(aIID);
  1061.   }
  1062. };
  1063.  
  1064. /***********************************************************
  1065. module definition (xpcom registration)
  1066. ***********************************************************/
  1067. var WebMailNotifierModule = {
  1068.   registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
  1069.   {
  1070.     aCompMgr = aCompMgr.
  1071.         QueryInterface(Components.interfaces.nsIComponentRegistrar);
  1072.     aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME,
  1073.         CONTRACT_ID, aFileSpec, aLocation, aType);
  1074.   },
  1075.  
  1076.   unregisterSelf: function(aCompMgr, aLocation, aType)
  1077.   {
  1078.     aCompMgr = aCompMgr.
  1079.         QueryInterface(Components.interfaces.nsIComponentRegistrar);
  1080.     aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);
  1081.   },
  1082.  
  1083.   getClassObject: function(aCompMgr, aCID, aIID)
  1084.   {
  1085.     if (!aIID.equals(Components.interfaces.nsIFactory))
  1086.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  1087.  
  1088.     if (aCID.equals(CLASS_ID))
  1089.       return WebMailNotifierFactory;
  1090.  
  1091.     throw Components.results.NS_ERROR_NO_INTERFACE;
  1092.   },
  1093.   canUnload: function(aCompMgr) { return true; }
  1094. };
  1095.  
  1096. /***********************************************************
  1097. module initialization
  1098.  
  1099. When the application registers the component, this function
  1100. is called.
  1101. ***********************************************************/
  1102. function NSGetModule(aCompMgr, aFileSpec) { return WebMailNotifierModule; }
  1103.  
  1104. /***********************************************************
  1105. CookieManager definition
  1106. ***********************************************************/
  1107. function CookieInfo(){
  1108. }
  1109. CookieInfo.prototype={
  1110.   getDomain:function(){
  1111.     if(this.domain){
  1112.       if(this.domain.charAt(0)!=".")return "."+this.domain;
  1113.       else return this.domain;
  1114.     }
  1115.     return this.uri.host;
  1116.   },
  1117.   getPath:function(){
  1118.     if(this.path)return this.path;
  1119.     var path=this.uri.path;
  1120.     var i=path.lastIndexOf("/");
  1121.     if(i==-1)return path;
  1122.     else return path.substring(0,i+1);
  1123.   },
  1124.   getExpiry:function(){
  1125.     if(!this.expires)return 0x7ffffffffffffdff;
  1126.     var exp=this.expires;
  1127.     exp=exp.replace(/-(.+?)-(\d{2}) /," $1 20$2 ").replace(/-/g," ");
  1128.     return Date.parse(exp)/1000;
  1129.   },
  1130.   toString:function(){
  1131.       var s=this.name+"="+this.value;
  1132.       for(var p in this){
  1133.         if(typeof this[p] == "function")continue;
  1134.         if(p=="httponly"||p=="secure"){
  1135.           s+="; "+p;
  1136.         }else if(p!="name"&&p!="value"&&p!="uri"){
  1137.           s+="; "+p+"="+this[p];
  1138.         }
  1139.       }
  1140.     return s;
  1141.   }
  1142. }
  1143. function CookieManager(){
  1144.   this.cookies=[];
  1145.   if("@mozilla.org/xre/app-info;1" in Components.classes){
  1146.     var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
  1147.                           .getService(Components.interfaces.nsIXULAppInfo);
  1148.     var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
  1149.                                  .getService(Components.interfaces.nsIVersionComparator);
  1150.     this.isNew=(versionChecker.compare(appInfo.platformVersion, "1.9") >= 0);
  1151.   }else{
  1152.     this.isNew=false;
  1153.   }
  1154. }
  1155. CookieManager.prototype={
  1156.   addCookies: function(aURI,aCookie){
  1157.     if(typeof(aURI)=="string"){
  1158.       var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  1159.                       .getService(Components.interfaces.nsIIOService);
  1160.       aURI=ioService.newURI(aURI,null,null);
  1161.     }
  1162.     aCookie=aCookie.split("\n");
  1163.     for each(var o in aCookie){
  1164.       var val=new CookieInfo();
  1165.       var ar=o.split(";");
  1166.       var t=ar[0].match(/(\S+?)=(.*)/);
  1167.  
  1168.       val["name"]=t[1];
  1169.       val["value"]=t[2];
  1170.  
  1171.       for(var i=1;i<ar.length;i++){
  1172.         if(ar[i]){
  1173.           var t=ar[i].replace( /^\s+/g,"");
  1174.           var f=t.match(/(\S+?)=(.*)/);
  1175.           if(f)val[f[1].toLowerCase()]=f[2];
  1176.           else{
  1177.             t=t.toLowerCase();
  1178.             if(t=="httponly"||t=="secure")val[t]=true;
  1179.             else val[t]="";
  1180.           }
  1181.         }
  1182.       }
  1183.       val.uri=aURI;
  1184.       this._insert(val);
  1185. //if(val.getPath()!=val.path)dout(val.getDomain()+" "+val.getPath()+" "+val.domain+" "+val.path);
  1186.     }
  1187.   },
  1188.   _insert: function(val){
  1189.     for(var i in this.cookies){
  1190.       var o=this.cookies[i];
  1191.       if(o.name==val.name&&o.getDomain()==val.getDomain()&&o.getPath()==val.getPath()){
  1192.         this.cookies[i]=val;
  1193.         return;
  1194.       }
  1195.     }
  1196.     this.cookies.push(val);
  1197.   },
  1198.   findCookie:function(urispec,name){
  1199.     for each(var o in this.cookies){
  1200.       if(o.uri.spec==urispec&&o.name==name){
  1201.         return o.toString();
  1202.       }
  1203.     }
  1204.     return null;
  1205.   },
  1206.   getCookie: function(aURI){
  1207.     var str="";
  1208.     for each(var o in this.cookies){
  1209.       var domain=o.getDomain();
  1210.       if(domain.charAt(0)==".")domain=domain.substring(1);
  1211.       if(aURI.host.lastIndexOf(domain)==-1)continue;
  1212.       if(aURI.path.indexOf(o.getPath())!=0)continue;
  1213.       if(o.secure&&aURI.scheme!="https")continue;
  1214.       var exp=o.expires;
  1215.       if(exp){
  1216.         exp=exp.replace(/-(.+?)-(\d{2}) /," $1 20$2 ").replace(/-/g," ");
  1217.         if(Date.parse(exp)<new Date()){
  1218.           continue;
  1219.         }
  1220.       }
  1221.       var s=o.name+"="+o.value;
  1222.       if(str)str+="; "+s;
  1223.       else str=s;
  1224.     }
  1225.     return str;
  1226.   },
  1227.   setCookieToBrowser: function(){
  1228.     var cm = Components.classes["@mozilla.org/cookiemanager;1"]
  1229.               .getService(Components.interfaces.nsICookieManager2);
  1230.     for each(var o in this.cookies){
  1231. //if(!o.expires)dout(o.name+" "+o.getExpiry());
  1232.       if (this.isNew){
  1233.         cm.add(o.getDomain(),o.getPath(),o.name,o.value,o.secure,o.httponly,!o.expires,o.getExpiry());
  1234.       }else{
  1235.         cm.add(o.getDomain(),o.getPath(),o.name,o.value,o.secure,!o.expires,o.getExpiry());
  1236.       }
  1237.     }
  1238.   },
  1239.   clear: function(){
  1240.     this.cookies=[];
  1241.   }
  1242. }
  1243. /***********************************************************
  1244. WebMailHandler definition
  1245. ***********************************************************/
  1246. function WebMailHandler(webMailNotifier){
  1247.   this.main=webMailNotifier;
  1248.   this.cookieManager=new CookieManager();
  1249.   this.loggedIn=false;
  1250.   this.reset();
  1251. }
  1252. WebMailHandler.prototype={
  1253.   charSet: null,
  1254.   data: "",
  1255.   stage: 0,
  1256.   initStage: ST_LOGIN,
  1257.   mailCount:-1,
  1258.   mailData:{},
  1259.   user: "",
  1260.   password: null,
  1261.   loginData:[],
  1262.   started:false,
  1263.   // nsIChannelEventSink
  1264.   onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
  1265.     if(this.channel==aOldChannel)this.channel = aNewChannel;
  1266.   },
  1267.   // nsIInterfaceRequestor
  1268.   getInterface: function (aIID) {
  1269.     try {
  1270.       return this.QueryInterface(aIID);
  1271.     } catch (e) {
  1272. //dout("getInterface "+aIID);
  1273.       throw Components.results.NS_NOINTERFACE;
  1274.     }
  1275.   },
  1276.   // nsIProgressEventSink
  1277.   onProgress : function (aRequest, aContext, aProgress, aProgressMax) { },
  1278.   onStatus : function (aRequest, aContext, aStatus, aStatusArg) { },
  1279.   // nsIHttpEventSink
  1280.   onRedirect : function (aOldChannel, aNewChannel) { },
  1281.   // nsIAuthPromptProvider
  1282.   getAuthPrompt : function(aReason){ return null; },
  1283.   QueryInterface : function(aIID) {
  1284.     if (aIID.equals(Components.interfaces.nsISupports) ||
  1285.         aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
  1286.         aIID.equals(Components.interfaces.nsIChannelEventSink) ||
  1287.         aIID.equals(Components.interfaces.nsIProgressEventSink) ||
  1288.         aIID.equals(Components.interfaces.nsIHttpEventSink) ||
  1289.         aIID.equals(Components.interfaces.nsIStreamListener)||
  1290.         aIID.equals(Components.interfaces.nsIAuthPromptProvider)||
  1291.         aIID.equals(Components.interfaces.nsIPrompt)|| //not used but required in ff 2.0
  1292.         aIID.equals(Components.interfaces.nsIDocShell)|| //required in ff 3.0
  1293.         aIID.equals(Components.interfaces.nsIAuthPrompt))
  1294.       return this;
  1295. //dout("QueryInterface "+aIID);
  1296.     throw Components.results.NS_NOINTERFACE;
  1297.   },
  1298.   onStartRequest : function (aRequest, aContext) {
  1299.     this.data = "";
  1300.   },
  1301.   onDataAvailable : function (aRequest, aContext, aStream, aSourceOffset, aLength){
  1302.       var is = Components.classes["@mozilla.org/scriptableinputstream;1"]
  1303.             .createInstance(Components.interfaces.nsIScriptableInputStream);
  1304.       is.init(aStream);
  1305.       this.data += is.read(aLength);
  1306.   },
  1307.   onStopRequest : function (aRequest, aContext, aStatus) {
  1308.     if(aStatus==Components.results.NS_BINDING_ABORTED)return;
  1309.     var charSet=null;
  1310.     var httpChannel=aRequest.QueryInterface(Components.interfaces.nsIHttpChannel);
  1311.     if(this.charSet)charSet=this.charSet;
  1312.     else{
  1313.       var fnd=this.data.match(/<meta.+?\".+?charset=(\S+?)\s*?;?\s*?\"\s*?\x2f?>/);
  1314.       if(fnd)charSet=fnd[1];
  1315.       else{
  1316.         try{
  1317.           if(httpChannel.contentCharset)charSet=httpChannel.contentCharset;
  1318.         }catch(e){}
  1319.       }
  1320.     }
  1321.     if(charSet){
  1322.       var uniConv = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
  1323.                                       .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  1324.       uniConv.charset = charSet;
  1325.       try{
  1326.         this.data=uniConv.ConvertToUnicode(this.data);
  1327.       }catch(e){}
  1328.     }
  1329.     try{
  1330.       if(!this.process(aContext.QueryInterface(Components.interfaces.nsIHttpChannel), this.data))++this.stage;
  1331.     }catch(e){
  1332.       this.onError();
  1333. dout(this.id+" "+e);
  1334.     }
  1335.   },
  1336.   stop : function(){
  1337.     if(this.channel){
  1338.       this.channel.cancel(Components.results.NS_BINDING_ABORTED);
  1339.     }
  1340.   },
  1341.   process : function (aHttpChannel, aData){
  1342.     switch(this.stage){
  1343.     case ST_LOGIN:
  1344.       this.getHtml(this.loginData[LOGIN_URL],this.loginData[LOGIN_POST]);
  1345.       return false;
  1346.     case ST_LOGIN_RES:
  1347.       this.stage=ST_DATA;
  1348.     case ST_DATA:
  1349.       if(!this.dataURLCopy){
  1350.         if(this.allDataURL&&!this.isInboxOnly())this.dataURLCopy=this.allDataURL;
  1351.         else this.dataURLCopy=this.dataURL;
  1352.       }
  1353.       this.getHtml(this.dataURLCopy);
  1354.       return false;
  1355.     case ST_DATA_RES:
  1356.       this.mailCount=this.getCount(aData);
  1357.       this.mailData=this.getData(aData);
  1358.       this.mailData.desc=this.getDesc();
  1359.       try{
  1360.         if(this.mailCount>=0&&aHttpChannel!=null&&aHttpChannel.responseStatus==302){
  1361.           /*var l=aHttpChannel.getResponseHeader("Location");
  1362.           if(l.indexOf("http")==0){
  1363.             this.dataURLCopy=l;
  1364.           }else{
  1365.             if(l.indexOf("/")==0){
  1366.               this.dataURLCopy=aHttpChannel.URI.scheme+"://"+aHttpChannel.URI.hostPort+l;
  1367.             }
  1368.           }*/
  1369.           this.dataURLCopy=this.channel.URI.spec;
  1370.         }
  1371.       }catch(e){
  1372. dout(e);
  1373.       }
  1374.       if(this.mailCount<0)this.reset();
  1375.       else this.stage=ST_DATA;
  1376.       this.main.setState(nsIWebMailNotifier.ST_MAILDATA,this.ind);
  1377.       if(this.main.autoLogin){
  1378.         if(this.mailCount>=0&&!this.loggedIn&&this.main.isDefault(this.id,this.user)){
  1379.           this.loggedIn=true;
  1380.           this.cookieManager.setCookieToBrowser();
  1381.         }
  1382.       }
  1383.       return true;
  1384.     }
  1385. dout("[onError] "+this.id+" "+this.user+" "+this.stage);
  1386.     this.onError();
  1387.     return true;
  1388.   },
  1389.   onError : function(){
  1390.     this.reset();
  1391.     this.main.setState(nsIWebMailNotifier.ST_MAILDATA,this.ind);
  1392.   },
  1393.   reset : function(){
  1394.     this.mailCount=-1;
  1395.     this.mailData={};
  1396.     this.mailData.desc=this.getDesc();    
  1397.     this.stage=this.initStage;
  1398.     this.dataURLCopy=null;
  1399.     this.cookieManager.clear();
  1400.   },
  1401.   checkMail : function(){
  1402.     if(!this.enabled)return;
  1403.     this.stop();
  1404.     //this.stage=this.mailCount<0?this.initStage:ST_DATA;
  1405.     if(this.mailCount<0)this.reset();
  1406.     else this.stage=ST_DATA;
  1407.     this.started=true;
  1408.     try{
  1409.       if(!this.process(null,""))++this.stage;
  1410.     }catch(e){
  1411.       this.onError();
  1412. dout(this.id+" "+e);
  1413.     }
  1414.   },
  1415.   onRequest : function(aHttpChannel){
  1416.     var ck=this.cookieManager.getCookie(aHttpChannel.URI);
  1417.     aHttpChannel.setRequestHeader("Cookie",ck, false);
  1418.   },
  1419.   onResponse : function(aHttpChannel){
  1420.     try {
  1421.       var cookie = aHttpChannel.getResponseHeader("Set-Cookie");
  1422.       this.cookieManager.addCookies(aHttpChannel.URI,cookie);
  1423.       aHttpChannel.setResponseHeader("Set-Cookie", "", false);
  1424.     }catch(e){}
  1425.   },
  1426.   getMailURL : function(aFolder){
  1427.     return this.mailURL;
  1428.   },
  1429.   getIconURL : function(){
  1430.     try{
  1431.       var url=this.mailURL.match(/(((\S+):\/\/([^/]+))(\S*\/)?)([^/]*)/);
  1432.       if(url)return url[2]+"/favicon.ico";
  1433.     }catch(e){}
  1434.     return null;
  1435.   },
  1436.   getData : function(aData){
  1437.     return {};
  1438.   },
  1439.   getDesc : function(){
  1440.     var n=this.calcCount();
  1441.     return n>=0?n:"";
  1442.   },
  1443.   calcCount : function() {
  1444.     var aCount=this.mailCount;
  1445.     if(this.main.newMailsOnly){
  1446.       if(aCount>=0){
  1447.         var prefStr="accounts."+this.id+"."+this.user+".count";
  1448.         var count=null;
  1449.         try{
  1450.           count=this.main.prefBranch.getIntPref(prefStr);
  1451.         }catch(e){}
  1452.         if(count==null){
  1453.           this.main.prefBranch.setIntPref(prefStr,0);
  1454.           count=0;
  1455.         }
  1456.         if(aCount>=count)aCount-=count;
  1457.         else{
  1458.           this.main.prefBranch.setIntPref(prefStr,aCount>0?aCount:0);
  1459.           aCount=0;
  1460.         }
  1461.       }
  1462.     }
  1463.     return aCount;
  1464.   }
  1465. };
  1466. WebMailHandler.prototype.baseProcess=WebMailHandler.prototype.process
  1467. WebMailHandler.prototype.baseGetData=WebMailHandler.prototype.getData
  1468. /***********************************************************
  1469. load html
  1470. ***********************************************************/
  1471. WebMailHandler.prototype.getHtml = function(aURL,aPostData,aHeaders) {
  1472.   var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  1473.   var uri = ioService.newURI(aURL, null, null);
  1474.   var channel = ioService.newChannelFromURI(uri);
  1475.   var httpChannel = channel.QueryInterface(Components.interfaces.nsIHttpChannel);
  1476.   if (aPostData) {
  1477.     var uploadStream = Components.classes["@mozilla.org/io/string-input-stream;1"]
  1478.                         .createInstance(Components.interfaces.nsIStringInputStream);
  1479.     uploadStream.setData(aPostData, aPostData.length);
  1480.     var uploadChannel = channel.QueryInterface(Components.interfaces.nsIUploadChannel);
  1481.     uploadChannel.setUploadStream(uploadStream, "application/x-www-form-urlencoded", -1);
  1482.     httpChannel.requestMethod = "POST";
  1483.   }
  1484.   if(aHeaders){
  1485.     for(var t in aHeaders){
  1486.       httpChannel.setRequestHeader(t,aHeaders[t],false);
  1487.     }
  1488.   }
  1489.   this.channel=channel;
  1490.   channel.notificationCallbacks = this;
  1491.   channel.asyncOpen(this,httpChannel);
  1492. }
  1493. WebMailHandler.prototype.isInboxOnly = function(){
  1494.   if(!this.supportInboxOnly)return true;
  1495.   var s="accounts."+this.id+"."+this.user+".inboxOnly";
  1496.   try{
  1497.     return this.main.prefBranch.getBoolPref(s);
  1498.   }catch(e){
  1499.     this.main.prefBranch.setBoolPref(s,true);
  1500.   }
  1501.   return true;
  1502. }
  1503. WebMailHandler.prototype.isShowFolders = function(){
  1504.   if(!this.supportShowFolders)return true;
  1505.   var s="accounts."+this.id+"."+this.user+".showFolders";
  1506.   try{
  1507.     return this.main.prefBranch.getBoolPref(s);
  1508.   }catch(e){
  1509.     this.main.prefBranch.setBoolPref(s,true);
  1510.   }
  1511.   return true;
  1512. }
  1513. WebMailHandler.prototype.getCookie = function(domain,name){
  1514.   var obj = Components.classes["@mozilla.org/cookiemanager;1"].
  1515.               getService(Components.interfaces.nsICookieManager2);
  1516.   var enm = obj.enumerator;
  1517.   while(enm.hasMoreElements()){
  1518.     var ck = enm.getNext();
  1519.     ck.QueryInterface(Components.interfaces.nsICookie2);
  1520.     if(ck.host.lastIndexOf(domain)!=-1&&ck.name==name&&!ck.isSession)return ck;
  1521.   }
  1522.   return null;
  1523. };
  1524. WebMailHandler.prototype.getCookieString = function(domain,name){
  1525.   var ck=this.getCookie(domain,name);
  1526.   if(!ck)return null;
  1527.   var s=ck.name+"="+ck.value;
  1528.   if(ck.expires!=0)s+="; expires="+new Date(ck.expires*1000).toUTCString();
  1529.   if(ck.path)s+="; path="+ck.path;
  1530.   if(ck.host)s+="; domain="+ck.host;
  1531.   if(ck.secure)s+="; secure";
  1532.   if(ck.httponly)s+="; httponly";
  1533.   return s;
  1534. };
  1535.  
  1536. function encodeObject(data){
  1537.   var s="";
  1538.   for(var i in data){
  1539.     if(s)s+=",";
  1540.     s+=escape(i)+":"+escape(data[i]);
  1541.   }
  1542.   return s;
  1543. }
  1544. function encodeArray(data){
  1545.   var s="";
  1546.   for(var i=0;i<data.length;i++){
  1547.     if(s)s+=",";
  1548.     s+=escape(data[i]);
  1549.   }
  1550.   return s;
  1551. }
  1552. ////////////////for debug//////////////////////////////////
  1553. function dlog(str){
  1554.   dout(str);
  1555.   var name="wmn-log.txt";
  1556.   if(enableDebug==2)this.notFirst=true;
  1557.   str=new Date()+"\t"+str.replace(/\r/g,"\\r").replace(/\n/g,"\\n")+"\r\n";
  1558.   WebMailNotifier.prototype.saveFile("wmn-log.txt",str,this.notFirst);
  1559. }
  1560. ///////////////////////////////////////////////////////////
  1561.